'''
Author: LostPatrol_3
Date: 2023-11-04 17:20:05
LastEditors: LostPatrol_3
LastEditTime: 2023-11-06 20:07:36
Description: TCP socket server running on linux
'''
import socket
import json
import time
from datetime import datetime

PATCH_SIZE = 1024
MAX_FILE_LENGTH = 1024 * 1024 * 10
MAX_SINGAL_SIZE = 8192
MAX_MEMBER = 10

def start_server():
    host = "0.0.0.0"
    port = 12345

    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.setblocking(False)
    server_socket.bind((host, port))
    server_socket.listen(MAX_MEMBER)

    print(f"Server start listening on port {port}...")

    client_socket = None

    while not client_socket:
        client_socket, addr = server_socket.accept()
        print(f"Accepted connection from {addr}")

    while True:
        time.sleep(0.5)
        data = client_socket.recv(PATCH_SIZE)
        print(f"raw message received from client:{data}")
        try:
            data = data.decode()
            print(f"decoded message: {data}")
        except Exception as e:
            print("failed to decode message")
            print(e)
        if data is None or len(data) == 0:
            continue
        try:
            data = json.loads(data)
            if data['type'] == 'text':
                # data = data['data']
                client_socket.send(json.dumps({'type':'text', 'user': data['user'],'time':data['time'], 'data':data['data']}).encode())
                # client_socket.send(json.dump(data))
            elif data['type'] == 'image':
                image_size = data['imageSize']
                if image_size > MAX_FILE_LENGTH:
                    print('too large image message, skip')
                    continue
                client_socket.send(json.dumps({'type':'image', 'imageSize':image_size}).encode())
                time.sleep(0.1)
                # image file is sent in binary code (bytes)
                print("start receiving image from client")
                # 接收部分是从缓冲区读取数据, 存在上限, 无法通过设置大参数一次性读出所有数据
                # 需要循环读取, 待缓冲区没有数据后将数据拼接
                image_data = b''
                while len(image_data) < image_size:
                    data = client_socket.recv(PATCH_SIZE) 
                    if data is None or len(data) == 0:
                        break
                    image_data += data
                    
                print("end receiving image from client")
                time.sleep(0.1)
                # so it can be sent to client directly
                # client_socket.send(data)
                print("start sending image to client")
                if image_size <= MAX_SINGAL_SIZE:
                    client_socket.send(image_data)
                else:
                    try:
                        client_socket.sendall(image_data)
                    except Exception as e:
                        print("failed to send image data to client")
                        print(e)

                print("end sending image to client")
        except Exception as e:
            print(e)
            continue
        

def process_text():
    pass

def process_picture():
    pass

if __name__ == "__main__":
    start_server()
